
package com.trydofor.id.body.int64;

import com.trydofor.aloe.exception.Exceptions;
import com.trydofor.id.byta.Bytable;
import com.trydofor.id.byta.ByteMeta;
import com.trydofor.id.byta.Bytes;

/**
 * fetch the count of long from the maker.
 * 
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class Int64QueryBody implements Bytable<Int64QueryBody> {
    
    private final String maker;
    private final int    count;
    
    /**
     * constructor.
     * 
     * @param maker the maker to fetch.
     * @param count the count to fetch.
     * @throws IllegalArgumentException if type or size is Not positive.
     * @throws NullPointerException if type is null
     */
    public Int64QueryBody(String maker, int count) {
        Exceptions.checkNullPointer(maker);
        Exceptions.checkIllegalArgument(count < 0, "the count must be positive.");
        
        this.maker = maker;
        this.count = count;
    }
    
    /**
     * {@inheritDoc}
     */
    public byte[] toBytes() {
        byte[] tps = Bytes.toMetaBytes(maker);
        byte[] bytes = new byte[tps.length + Bytes.BYTES_INT];
        System.arraycopy(tps, 0, bytes, 0, tps.length);
        Bytes.fill(bytes, tps.length, count);
        return bytes;
    }
    
    /**
     * {@inheritDoc}
     */
    public Int64QueryBody ofBytes(byte[] bs, int offset, int length) {
        ByteMeta<Int64QueryBody> bm = ofBytes(bs, offset);
        return (bm.byteSize() != length) ? null : bm.instance();
    }
    
    /**
     * {@inheritDoc}
     */
    public ByteMeta<Int64QueryBody> ofBytes(byte[] bs, int offset) {
        Int64QueryBody inst = null;
        int size = 0;
        int miniSize = Bytes.BYTES_INT * 2;
        if (bs != null && bs.length - offset >= miniSize) {
            ByteMeta<String> tps = Bytes.ofMetaBytes(bs, offset);
            int count = Bytes.toInt(bs, offset + tps.byteSize(), Bytes.BYTES_INT);
            String mk = tps.instance();
            if (mk != null) {
                inst = new Int64QueryBody(mk, count);
                size = tps.byteSize() + Bytes.BYTES_INT;
            }
        }
        
        return ByteMeta.of(inst, size);
    }
    
    /**
     * @return the maker
     */
    public String getMaker() {
        return maker;
    }
    
    /**
     * @return the count
     */
    public int getCount() {
        return count;
    }
    
    /**
     * {@inheritDoc}
     */
    public String toString() {
        return "maker=" + maker + ",limit=" + count;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + count;
        result = prime * result + ((maker == null) ? 0 : maker.hashCode());
        return result;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Int64QueryBody)) {
            return false;
        }
        Int64QueryBody other = (Int64QueryBody) obj;
        if (count != other.count) {
            return false;
        }
        if (maker == null) {
            if (other.maker != null) {
                return false;
            }
        }
        else if (!maker.equals(other.maker)) {
            return false;
        }
        return true;
    }
    
}
